﻿#include "FITKAbaqusHDF5AdaptorProfile.h"

#include "FITK_Kernel/FITKCore/FITKEnumTransformer.hpp"

#include "FITK_Interface/FITKInterfaceIO/FITKAbstractHDF5Reader.h"
#include "FITK_Interface/FITKInterfaceIO/FITKAbstractHDF5Writer.h"

#include "FITK_Interface/FITKInterfaceStructural/FITKAbaProfile.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaProfileI.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaProfileL.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaProfileCircular.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaProfilePipe.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaProfileRectangular.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaProfileBox.h"

#include "FITK_Interface/FITKInterfaceStructural/FITKAbaProfileManager.h"

namespace IO
{
    QString FITKAbaqusHDF5AdaptorProfile::getAdaptorClass()
    {
        return "FITKAbaqusHDF5AdaptorProfile";
    }

    bool FITKAbaqusHDF5AdaptorProfile::adaptR()
    {
        auto abaqusProfile = dynamic_cast<Interface::FITKAbaProfile*>(_dataObj);
        if (!_reader || !_h5Group || !abaqusProfile) return false;
        bool isR = true;
        isR &= readProfile(abaqusProfile, *_h5Group);
        return isR;
    }

    bool FITKAbaqusHDF5AdaptorProfile::adaptW()
    {
        auto abaqusProfile = dynamic_cast<Interface::FITKAbaProfile*>(_dataObj);
        if (!_writer || !_h5Group || !abaqusProfile) return false;
        bool isW = true;
        isW &= writeProfile(abaqusProfile, *_h5Group);
        return isW;
    }

    bool FITKAbaqusHDF5AdaptorProfile::readProfile(Interface::FITKAbaProfile* profile, H5::Group& h5Group)
    {
        if (!profile || h5Group.getLocId() == -1) return false;
        bool isR = true;
        isR &= readNDataObject(profile, h5Group);
        auto shapeType = profile->getShape();
        if (shapeType == Interface::FITKAbaProfile::FITKAbaProfileShape::Box)
        {
            isR &= readProfileBox(profile, h5Group);
        }
        else if (shapeType == Interface::FITKAbaProfile::FITKAbaProfileShape::Circular)
        {
            isR &= readProfileCircular(profile, h5Group);
        }
        else if (shapeType == Interface::FITKAbaProfile::FITKAbaProfileShape::I)
        {
            isR &= readProfileI(profile, h5Group);
        }
        else if (shapeType == Interface::FITKAbaProfile::FITKAbaProfileShape::L)
        {
            isR &= readProfileL(profile, h5Group);
        }
        else if (shapeType == Interface::FITKAbaProfile::FITKAbaProfileShape::Pipe)
        {
            isR &= readProfilePipe(profile, h5Group);
        }
        else if (shapeType == Interface::FITKAbaProfile::FITKAbaProfileShape::Rectangular)
        {
            isR &= readProfileRectangular(profile, h5Group);
        }
        else
        {
            return false;
        }
        return true;
    }

    bool FITKAbaqusHDF5AdaptorProfile::readProfileBox(Interface::FITKAbaProfile* profile, H5::Group& h5Group)
    {
        Interface::FITKAbaProfileBox* profileBox = dynamic_cast<Interface::FITKAbaProfileBox*>(profile);
        if (!profileBox) return false;
        bool isValid = false;
        double width = readDoubleAttribute(h5Group, "Width");
        double height = readDoubleAttribute(h5Group, "Height");
        auto sBoxThicknessType = readStrAttribute(h5Group, "BoxThicknessType");
        Core::FITKEnumTransfer<Interface::FITKAbaProfileBox::BoxThickness> fitkTypeTrafer;
        auto eBoxThicknessType = fitkTypeTrafer.fromString(QString::fromStdString(sBoxThicknessType), isValid);
        if (!isValid) return false;

        double thickness = readDoubleAttribute(h5Group, "Thickness");
        double T1 = readDoubleAttribute(h5Group, "T1");
        double T2 = readDoubleAttribute(h5Group, "T2");
        double T3 = readDoubleAttribute(h5Group, "T3");
        double T4 = readDoubleAttribute(h5Group, "T4");

        profileBox->setWidth(width);
        profileBox->setHeight(height);
        profileBox->setThicknessType(eBoxThicknessType);
        profileBox->setThickness(thickness);
        profileBox->setT1(T1);
        profileBox->setT2(T2);
        profileBox->setT3(T3);
        profileBox->setT4(T4);
        return true;
    }

    bool FITKAbaqusHDF5AdaptorProfile::readProfileCircular(Interface::FITKAbaProfile* profile, H5::Group& h5Group)
    {
        Interface::FITKAbaProfileCircular* profileCircular = dynamic_cast<Interface::FITKAbaProfileCircular*>(profile);
        if (!profileCircular) return false;
        double R = readDoubleAttribute(h5Group, "R");
        profileCircular->setR(R);
        return true;
    }

    bool FITKAbaqusHDF5AdaptorProfile::readProfileI(Interface::FITKAbaProfile* profile, H5::Group& h5Group)
    {
        Interface::FITKAbaProfileI* profileI = dynamic_cast<Interface::FITKAbaProfileI*>(profile);
        if (!profileI) return false;
        double l = readDoubleAttribute(h5Group, "l");
        double h = readDoubleAttribute(h5Group, "h");
        double b1 = readDoubleAttribute(h5Group, "b1");
        double b2 = readDoubleAttribute(h5Group, "b2");
        double t1 = readDoubleAttribute(h5Group, "t1");
        double t2 = readDoubleAttribute(h5Group, "t2");
        double t3 = readDoubleAttribute(h5Group, "t3");

        profileI->setI(l);
        profileI->seth(h);
        profileI->setb1(b1);
        profileI->setb2(b2);
        profileI->sett1(t1);
        profileI->sett2(t2);
        profileI->sett3(t3);

        return true;
    }

    bool FITKAbaqusHDF5AdaptorProfile::readProfileL(Interface::FITKAbaProfile* profile, H5::Group& h5Group)
    {
        Interface::FITKAbaProfileL* profileL = dynamic_cast<Interface::FITKAbaProfileL*>(profile);
        if (!profileL) return false;
        double A = readDoubleAttribute(h5Group, "A");
        double B = readDoubleAttribute(h5Group, "B");
        double T1 = readDoubleAttribute(h5Group, "T1");
        double T2 = readDoubleAttribute(h5Group, "T2");
        profileL->setA(A);
        profileL->setB(B);
        profileL->setT1(T1);
        profileL->setT2(T2);
        return true;
    }

    bool FITKAbaqusHDF5AdaptorProfile::readProfilePipe(Interface::FITKAbaProfile* profile, H5::Group& h5Group)
    {
        Interface::FITKAbaProfilePipe* profilePipe = dynamic_cast<Interface::FITKAbaProfilePipe*>(profile);
        if (!profilePipe) return false;
        bool isValid = false;
        auto sFormulation = readStrAttribute(h5Group, "Formulation");
        Core::FITKEnumTransfer<Interface::FITKAbaProfilePipe::PipeFormulation> fitkTypeTrafer;
        auto eFormulation = fitkTypeTrafer.fromString(QString::fromStdString(sFormulation), isValid);
        if (!isValid) return false;
        profilePipe->setFormulation(eFormulation);

        double Radius = readDoubleAttribute(h5Group, "Radius");
        profilePipe->setRadius(Radius);
        double Thickness = readDoubleAttribute(h5Group, "Thickness");
        profilePipe->setThickness(Thickness);
        return true;
    }

    bool FITKAbaqusHDF5AdaptorProfile::readProfileRectangular(Interface::FITKAbaProfile* profile, H5::Group& h5Group)
    {
        Interface::FITKAbaProfileRectangular* profileRectangular = dynamic_cast<Interface::FITKAbaProfileRectangular*>(profile);
        if (!profileRectangular) return false;
        double A = readDoubleAttribute(h5Group, "A");
        double B = readDoubleAttribute(h5Group, "B");
        profileRectangular->setA(A);
        profileRectangular->setB(B);
        return true;
    }

    bool FITKAbaqusHDF5AdaptorProfile::writeProfile(Interface::FITKAbaProfile* profile, H5::Group& h5Group)
    {
        if (!profile || h5Group.getLocId() == -1) return false;
        bool isValid = false;

        std::string groupName = createParentAttribute(profile, h5Group);
        if (groupName.empty())return false;

        _h5CreateGroup = h5Group.createGroup(groupName);
        bool isW = true;
        auto eShapeType = profile->getShape();

        //枚举转换字符
        Core::FITKEnumTransfer<Interface::FITKAbaProfile::FITKAbaProfileShape> fitkITTypeTrafer;
        auto sShapeType = fitkITTypeTrafer.toStrting(eShapeType, isValid);
        if (!isValid) return false;
        writeStrAttribute(_h5CreateGroup, "Type", sShapeType.toStdString());

        if (eShapeType == Interface::FITKAbaProfile::FITKAbaProfileShape::Box)
        {
            isW &= writeProfileBox(profile, _h5CreateGroup);
        }
        else if (eShapeType == Interface::FITKAbaProfile::FITKAbaProfileShape::Circular)
        {
            isW &= writeProfileCircular(profile, _h5CreateGroup);
        }
        else if (eShapeType == Interface::FITKAbaProfile::FITKAbaProfileShape::I)
        {
            isW &= writeProfileI(profile, _h5CreateGroup);
        }
        else if (eShapeType == Interface::FITKAbaProfile::FITKAbaProfileShape::L)
        {
            isW &= writeProfileL(profile, _h5CreateGroup);
        }
        else if (eShapeType == Interface::FITKAbaProfile::FITKAbaProfileShape::Pipe)
        {
            isW &= writeProfilePipe(profile, _h5CreateGroup);
        }
        else if (eShapeType == Interface::FITKAbaProfile::FITKAbaProfileShape::Rectangular)
        {
            isW &= writeProfileRectangular(profile, _h5CreateGroup);
        }
        else
        {
            return false;
        }
        isW &= writeNDataObject(profile, _h5CreateGroup);
        return true;
    }

    bool FITKAbaqusHDF5AdaptorProfile::writeProfileBox(Interface::FITKAbaProfile* profile, H5::Group& h5Group)
    {
        Interface::FITKAbaProfileBox* profileBox = dynamic_cast<Interface::FITKAbaProfileBox*>(profile);
        if (!profileBox) return false;
        bool isValid = false;
        double width = profileBox->getWidth();
        double height = profileBox->getHeight();

        //枚举转换字符
        Interface::FITKAbaProfileBox::BoxThickness eBoxThickness = profileBox->getThicknessType();
        Core::FITKEnumTransfer<Interface::FITKAbaProfileBox::BoxThickness> fitkTypeTrafer;
        auto sBoxThickness = fitkTypeTrafer.toStrting(eBoxThickness, isValid);
        if (!isValid) return false;

        auto thickness = profileBox->getThickness();
        double T1 = profileBox->getT1();
        double T2 = profileBox->getT2();
        double T3 = profileBox->getT3();
        double T4 = profileBox->getT4();

        writeDoubleAttribute(h5Group, "Width", &width);
        writeDoubleAttribute(h5Group, "Height", &height);
        writeStrAttribute(h5Group, "BoxThicknessType", sBoxThickness.toStdString());
        writeDoubleAttribute(h5Group, "Thickness", &thickness);
        writeDoubleAttribute(h5Group, "T1", &T1);
        writeDoubleAttribute(h5Group, "T2", &T2);
        writeDoubleAttribute(h5Group, "T3", &T3);
        writeDoubleAttribute(h5Group, "T4", &T4);
        return true;
    }

    bool FITKAbaqusHDF5AdaptorProfile::writeProfileCircular(Interface::FITKAbaProfile* profile, H5::Group& h5Group)
    {
        Interface::FITKAbaProfileCircular* profileCircular = dynamic_cast<Interface::FITKAbaProfileCircular*>(profile);
        if (!profileCircular) return false;
        double R = profileCircular->getR();
        writeDoubleAttribute(h5Group, "R", &R);
        return true;
    }

    bool FITKAbaqusHDF5AdaptorProfile::writeProfileI(Interface::FITKAbaProfile* profile, H5::Group& h5Group)
    {
        Interface::FITKAbaProfileI* profileI = dynamic_cast<Interface::FITKAbaProfileI*>(profile);
        if (!profileI) return false;
        double l = profileI->getI();
        double h = profileI->geth();
        double b1 = profileI->getb1();
        double b2 = profileI->getb2();
        double t1 = profileI->gett1();
        double t2 = profileI->gett2();
        double t3 = profileI->gett3();
        writeDoubleAttribute(h5Group, "l", &l);
        writeDoubleAttribute(h5Group, "h", &h);
        writeDoubleAttribute(h5Group, "b1", &b1);
        writeDoubleAttribute(h5Group, "b2", &b2);
        writeDoubleAttribute(h5Group, "t1", &t1);
        writeDoubleAttribute(h5Group, "t2", &t2);
        writeDoubleAttribute(h5Group, "t3", &t3);
        return true;
    }

    bool FITKAbaqusHDF5AdaptorProfile::writeProfileL(Interface::FITKAbaProfile* profile, H5::Group& h5Group)
    {
        Interface::FITKAbaProfileL* profileL = dynamic_cast<Interface::FITKAbaProfileL*>(profile);
        if (!profileL) return false;
        double A = profileL->getA();
        double B = profileL->getB();
        double T1 = profileL->getT1();
        double T2 = profileL->getT2();
        writeDoubleAttribute(h5Group, "A", &A);
        writeDoubleAttribute(h5Group, "B", &B);
        writeDoubleAttribute(h5Group, "T1", &T1);
        writeDoubleAttribute(h5Group, "T2", &T2);
        return true;
    }

    bool FITKAbaqusHDF5AdaptorProfile::writeProfilePipe(Interface::FITKAbaProfile* profile, H5::Group& h5Group)
    {
        Interface::FITKAbaProfilePipe* profilePipe = dynamic_cast<Interface::FITKAbaProfilePipe*>(profile);
        if (!profilePipe) return false;
        bool isValid = false;

        //枚举转换字符
        auto eFormulation = profilePipe->getFormulation();
        Core::FITKEnumTransfer<Interface::FITKAbaProfilePipe::PipeFormulation> fitkTypeTrafer;
        QString  sFormulation = fitkTypeTrafer.toStrting(eFormulation, isValid);
        if (!isValid) return false;
        writeStrAttribute(h5Group, "Formulation", sFormulation.toStdString());
        double Radius = profilePipe->getRadius();
        writeDoubleAttribute(h5Group, "Radius", &Radius);
        double Thickness = profilePipe->getThickness();
        writeDoubleAttribute(h5Group, "Thickness", &Thickness);
        return true;
    }

    bool FITKAbaqusHDF5AdaptorProfile::writeProfileRectangular(Interface::FITKAbaProfile* profile, H5::Group& h5Group)
    {
        Interface::FITKAbaProfileRectangular* profileRectangular = dynamic_cast<Interface::FITKAbaProfileRectangular*>(profile);
        if (!profileRectangular) return false;
        double A = profileRectangular->getA();
        double B = profileRectangular->getB();
        writeDoubleAttribute(h5Group, "A", &A);
        writeDoubleAttribute(h5Group, "B", &B);
        return true;
    }

}
